﻿using System;
using System.IO;
using UnityEngine;

public static class XKLog
{
    [System.Diagnostics.Conditional("ENABLE_LOG")]
    static public void Log(object message)
    {
        Debug.Log(message);
    }
    [System.Diagnostics.Conditional("ENABLE_LOG")]
    static public void Log(object message, UnityEngine.Object context)
    {
        Debug.Log(message, context);
    }

    [System.Diagnostics.Conditional("ENABLE_LOG")]
    public static void Log(UnityEngine.Object context, string format, params object[] args)
    {
        Debug.LogFormat(context, format, args);
    }

    [System.Diagnostics.Conditional("ENABLE_LOG")]
    public static void Log(LogType logType, LogOption logOptions, UnityEngine.Object context, string format, params object[] args)
    {
        Debug.LogFormat(logType, logOptions, context, format, args);
    }

    [System.Diagnostics.Conditional("ENABLE_LOG")]
    public static void Log(string format, params object[] args)
    {
        if (args.Length < 1)
        {
            Debug.Log(format);
        }
        else
        {
            Debug.LogFormat(format, args);
        }

    }

    [System.Diagnostics.Conditional("ENABLE_LOG")]
    public static void LogWarning(object message, UnityEngine.Object context)
    {
        Debug.LogWarning(message, context);
    }
    [System.Diagnostics.Conditional("ENABLE_LOG")]
    public static void LogWarning(object message)
    {
        Debug.LogWarning(message);
    }
    [System.Diagnostics.Conditional("ENABLE_LOG")]
    public static void LogWarning(UnityEngine.Object context, string format, params object[] args)
    {
        Debug.LogWarningFormat(context, format, args);
    }

    [System.Diagnostics.Conditional("ENABLE_LOG")]
    public static void LogWarning(string format, params object[] args)
    {
        if (args.Length < 1)
        {
            Debug.LogWarning(format);
        }
        else
        {
            Debug.LogWarningFormat(format, args);
        }
    }

    public static void LogError(object message)
    {
        Debug.LogError(message);
    }

    public static void LogError(object message, UnityEngine.Object context)
    {
        Debug.LogError(message, context);
    }

    public static void LogError(string format, params object[] args)
    {
        if (args.Length < 1)
        {
            Debug.LogError(format);
        }
        else
        {
            Debug.LogErrorFormat(format, args);
        }
    }

    public static void LogError(UnityEngine.Object context, string format, params object[] args)
    {
        Debug.LogErrorFormat(context, format, args);
    }
}


namespace SG
{

    public enum LogLevel
    {
        INFO,
        WARNING,
        ERROR,
    }

    public class LogMgr
    {
        public static int LogNet = 0;
        #region
        private static LogMgr m_instance;
        public static LogMgr Instance()
        {
            if (m_instance == null)
            {
                m_instance = new LogMgr();// obj.GetOrAddComponent<SceneMgr>();
                m_instance.DoInit();
            }
            return m_instance;
        }
        #endregion
        public void SetLogSwitch(bool value)
        {

        }

        #region 网络功能

        #endregion
        private StreamWriter writer = null;


        public delegate void MsgLog(string strMsg);

        public MsgLog UnityLog = new MsgLog(UnityEngine.Debug.Log);
        public MsgLog UnityError = new MsgLog(UnityEngine.Debug.LogError);
        public MsgLog UnityWarning = new MsgLog(UnityEngine.Debug.LogWarning);


        public void DoInit()
        {

        }
        // logLevel: log级别（info， warning， error）
        // strChannel: 频道
        // strMessage: log具体信息
        public void Log(LogLevel logLevel, string strChannel, string strMessage)
        {
            // 只在windows开发环境下运行才输出日志
            if (Application.platform != RuntimePlatform.WindowsEditor)
                return;

            if (writer == null)
                InitWriter();

            string strLog = " <" + (int)(Time.time * 1000) + ", " + logLevel.ToString() + ", " + strChannel + ">: " + strMessage;

            writer.WriteLine(strLog);
            writer.Flush();
        }

        private void WriteLog(LogLevel logLevel, string strChannel, string strMessage)
        {
            // 只在windows开发环境下运行才输出日志
            if (Application.platform != RuntimePlatform.WindowsEditor)
                return;

            if (writer == null)
                InitWriter();

            string strLog = " <" + (int)(Time.time * 1000) + ", " + logLevel.ToString() + ", " + strChannel + ">: " + strMessage;

            writer.WriteLine(strLog);
            writer.Flush();
        }

        private void InitWriter()
        {
            // 只在windows开发环境下运行才输出日志
            if (Application.platform != RuntimePlatform.WindowsEditor)
                return;

            string projectPath = Application.dataPath.Substring(0, Application.dataPath.LastIndexOf("/Assets"));
            string targetPath = projectPath + "/Log";
            Directory.CreateDirectory(targetPath);
            targetPath += "/log.log";

            writer = new StreamWriter(targetPath, false);
        }







        enum LOG_TYPE
        {
            DEGUG_LOG = 0,
            WARNING_LOG,
            ERROR_LOG
        }

        public delegate void OnOutputLog(string _msg);
        static public OnOutputLog onOutputLog = null;
        private void WriteLog(string msg, LOG_TYPE type, bool _showInConsole = false)
        {
            string strHead = "";
            switch (type)
            {
                case LOG_TYPE.DEGUG_LOG:
                    strHead = "Log:";
                    Debug.Log(strHead + msg);
                    break;
                case LOG_TYPE.ERROR_LOG:
                    strHead = "Error:";
                    Debug.LogError(strHead + msg);
                    break;
                case LOG_TYPE.WARNING_LOG:
                    strHead = "Waring:";
                    Debug.LogWarning(strHead + msg);
                    break;
                default:
                    strHead = "Other:";
                    Debug.Log(strHead + msg);
                    break;
            }

            //Client.Instance().Send( strHead + msg);
        }

        //public void ErrorLog(string fort, params object[] areges)
        //{

        //    if (areges.Length > 0)
        //    {
        //        string msg = string.Format(fort, areges);
        //        WriteLog(msg, LOG_TYPE.ERROR_LOG, true);
        //    }
        //    else
        //    {
        //        WriteLog(fort, LOG_TYPE.ERROR_LOG, true);
        //    }

        //}
        //public void WarningLog(string fort, params object[] areges)
        //{
        //    if (areges.Length > 0)
        //    {
        //        string msg = string.Format(fort, areges);
        //        WriteLog(msg, LOG_TYPE.WARNING_LOG, true);
        //    }
        //    else
        //    {
        //        WriteLog(fort, LOG_TYPE.WARNING_LOG, true);
        //    }
        //}
        //public void DebugLog(string fort, params object[] areges)
        //{
        //    if (areges.Length > 0)
        //    {
        //        string msg = string.Format(fort, areges);
        //        WriteLog(msg, LOG_TYPE.DEGUG_LOG, true);
        //    }
        //    else
        //    {
        //        WriteLog(fort, LOG_TYPE.DEGUG_LOG, true);
        //    }
        //}

        public void Log(string logString, string stackTrace, LogType type)
        {
            switch (type)
            {
                case LogType.Log:
                    Log(logString);
                    break;
                case LogType.Warning:
                    LogWarning(logString);
                    break;
                case LogType.Error:
                    LogError(logString);
                    break;
            }
        }

        #region


        /// <summary>
        /// 输出日志。
        /// </summary>
        /// <param name="format">日志格式。</param>
        /// <param name="args">日志参数。</param>
        [System.Diagnostics.Conditional("ENABLE_LOG")]
        public void Log(string format, params object[] args)
        {
            if (EnableLog)
            {
                string msg = string.Format(format, args);
                WriteLog(msg, LOG_TYPE.DEGUG_LOG, true);
            }
        }

        /// <summary>
        /// 输出警告日志。
        /// </summary>
        /// <param name="format">日志格式。</param>
        /// <param name="args">日志参数。</param>
        [System.Diagnostics.Conditional("ENABLE_LOG")]
        public void LogWarning(string format, params object[] args)
        {
            if (EnableLog)
            {
                string msg = string.Format(format, args);
                WriteLog(msg, LOG_TYPE.WARNING_LOG, true);
            }
        }

        /// <summary>
        /// 输出错误日志。
        /// </summary>
        /// <param name="format">日志格式。</param>
        /// <param name="args">日志参数。</param>
        public void LogError(string format, params object[] args)
        {
            if (EnableLog)
            {
                string msg = string.Format(format, args);
                WriteLog(msg, LOG_TYPE.ERROR_LOG, true);
            }
        }
        public void LogError(string format)
        {
            if (EnableLog)
            {

                WriteLog(format, LOG_TYPE.ERROR_LOG, true);
            }
        }


        /// <summary>
        /// 保存堆栈。
        /// </summary>
        /// <param name="text">堆栈内容。</param>
        public void SaveStackTrace(string text)
        {
#if UNITY_EDITOR
            //追加到文件
            string file = Application.dataPath + "/../StackTrace.log";
            FileStream stream = new FileStream(file, FileMode.OpenOrCreate);
            stream.Position = stream.Length;            //跳到末尾
            StreamWriter writer = new StreamWriter(stream);
            string t = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            writer.WriteLine(t);
            writer.WriteLine();
            writer.Write(text);
            writer.WriteLine();
            writer.WriteLine();
            writer.WriteLine();
            writer.Flush();
            writer.Close();
            writer.Dispose();
            writer = null;
            stream = null;
#endif
        }

        //#if UNITY_EDITOR

        //        [UnityEditor.Callbacks.OnOpenAssetAttribute(0)]
        //        static bool OnOpenAsset(int instanceID, int line)
        //        {
        //            //判断选中的文本是否还有类名
        //            string stackTrace = LogMgr.Instance().GetSourceText();
        //            if (!string.IsNullOrEmpty(stackTrace) && stackTrace.Contains(ClassName))
        //            {
        //                //匹配[文件路径:行号]部分 过滤出调用堆栈
        //                Match matches = Regex.Match(stackTrace, @"\(at (.+)\)", RegexOptions.IgnoreCase);
        //                bool xlua = false;
        //                while (matches.Success)
        //                {
        //                    //找到不是自身文件输出的那行即为日志输出调用行
        //                    string pathline = matches.Groups[1].Value;
        //                    if (!pathline.Contains(FileName))
        //                    {
        //                        //分析出文件路径与行号并用编辑器打开并指定对应行
        //                        int splitIndex = pathline.LastIndexOf(":");
        //                        string path = pathline.Substring(0, splitIndex);        //文件相对路径
        //                        line = System.Convert.ToInt32(pathline.Substring(splitIndex + 1));      //行号
        //                        string root = Application.dataPath.Substring(0, Application.dataPath.LastIndexOf("Assets"));    //根路径
        //                        string fullPath = (root + path).Replace('/', '\\');         //完整路径
        //                        if (xlua)
        //                        {
        //                            if (fullPath.EndsWith("LuaBehaviour.cs"))
        //                            {
        //                                UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(fullPath, line);   //打开并标记
        //                                break;
        //                            }
        //                        }
        //                        else
        //                        {
        //                            if (fullPath.EndsWith("XLua\\Src\\MethodWarpsCache.cs"))
        //                            {
        //                                xlua = true;
        //                            }
        //                            else
        //                            {
        //                                UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(fullPath, line);   //打开并标记
        //                                break;
        //                            }
        //                        }
        //                    }
        //                    matches = matches.NextMatch();
        //                }
        //                return true;
        //            }
        //            return false;
        //        }

        //        /// <summary>
        //        /// 获取控制台选中的文本。
        //        /// </summary>
        //        /// <returns>制台选中的文本。</returns>
        //        public string GetSourceText()
        //        {
        //            //获取控制台窗口
        //            Type ConsoleWindowType = typeof(EditorWindow).Assembly.GetType("UnityEditor.ConsoleWindow");
        //            FieldInfo info = ConsoleWindowType.GetField("ms_ConsoleWindow", BindingFlags.Static | BindingFlags.NonPublic);
        //            object wnd = info.GetValue(null);
        //            if (wnd != null && (object)EditorWindow.focusedWindow == wnd)
        //            {
        //                //获取当前选中的文本
        //                info = ConsoleWindowType.GetField("m_ActiveText", BindingFlags.Instance | BindingFlags.NonPublic);
        //                string activeText = info.GetValue(wnd).ToString();

        //                return activeText;
        //            }

        //            return null;
        //        }
        //#endif

#if UNITY_EDITOR
        /// <summary>
        /// 获取或设置是否启用日志。
        /// </summary>
        public static bool EnableLog = true;
#else
        /// <summary>
        /// 获取或设置是否启用日志。
        /// </summary>
        public static bool EnableLog = false;
#endif

        /// <summary>
        /// 类名。
        /// </summary>
        public static string ClassName = "SG.LogMgr";

        /// <summary>
        /// 文件名称。
        /// </summary>
        public static string FileName = "LogMgr.cs";

        /// <summary>
        /// 最大记录的日志数量。
        /// </summary>
        public static int MaxLogRecord = 20;


        #endregion
    }
}
